package com.example.fw;

import java.util.Calendar;
import java.util.List;

import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;

import com.example.fw.datamapping.ContactLine;
import com.example.tests.ContactData;
import com.example.utils.SortedListOf;

public class ContactHelper extends HelperBase {

	private SortedListOf<ContactLine> cahedContactLines;
	
	public static boolean CREATION = true;
	public static boolean MODIFICATION = false;
	
	public ContactHelper(ApplicationManager manager) {
		super(manager);
	}

	public void contactCreation(ContactData contact) {
		manager.navigateTo().mainPage();
		initContactCreation();
		fillContactCreation(contact, CREATION);
		submitContactCreation();
		returnToContactsPage();
	}

	public ContactData modifyContact(int index, ContactData contact) {
		manager.navigateTo().mainPage();
		initContactUpdateOrDelete(index);
		ContactData oldContact = extractContactDataFromEditForm();
		fillContactCreation(contact, MODIFICATION);
		submitContactModification();
		returnToContactsPage();
		
		return oldContact;
	}

	public void deleteContact(int index) {
		manager.navigateTo().mainPage();
		initContactUpdateOrDelete(index);
		submitContactDeletion();
		returnToContactsPage();		
	}
	
	public SortedListOf<ContactLine> getContactLines() {
		if (cahedContactLines == null) {
			rebuildCache();
		}
		return cahedContactLines;
	}
	
	private void rebuildCache() {
		cahedContactLines = new SortedListOf<ContactLine>();
		
		manager.navigateTo().mainPage();
		List<WebElement> rows = driver.findElements(By.xpath("//table/tbody/tr[@name='entry']"));
		for (WebElement row : rows) {
			ContactLine contactLine = getContactLineFromRaw(row);
			cahedContactLines.add(contactLine);
		}
	}
	
//----------------------------------------------------------------------------------------------------	
	public ContactHelper initContactCreation() {
		click(By.linkText("add new"));
		return this;
	}

	public ContactHelper initContactUpdateOrDelete(int index) {
		click(By.xpath("//tr["+(index+2)+"]/td[7]/a/img[@Title='Edit']"));
		return this;	
	}

	public ContactHelper submitContactCreation() {
		click(By.name("submit"));
		cahedContactLines = null;
		return this;
	}

	public ContactHelper submitContactModification() {
		click(By.xpath("//input[@value='Update']"));
		cahedContactLines = null;
		return this;
	}

	public ContactHelper submitContactDeletion() {
		click(By.xpath("//input[@value='Delete']"));
		cahedContactLines = null;
		return this;
	}

	public ContactLine getContactLineFromRaw(WebElement tableRaw){
		ContactLine contactLine = new ContactLine();
		//TODO: bug in the application. First name should be in "./td[2]"
		contactLine.fName = tableRaw.findElement(By.xpath("./td[3]")).getText();
		//TODO: bug in the application. Last name should be in "./td[3]"
		contactLine.lName = tableRaw.findElement(By.xpath("./td[2]")).getText();
		contactLine.email = tableRaw.findElement(By.xpath("./td[4]")).getText();
		contactLine.phone = tableRaw.findElement(By.xpath("./td[5]")).getText();
		
		contactLine.isPrimaryAddSet = !(tableRaw.findElements(By.xpath("./td[9]/a/img")).isEmpty());
		
		return contactLine;
	}
	
	public ContactHelper returnToContactsPage() {
		click(By.linkText("home page"));
		return this;
	}
	

	public ContactHelper fillContactCreation(ContactData contact, boolean formType) {
		type(By.name("firstname"),contact.getFName());
		type(By.name("lastname"),contact.getLName());
		type(By.name("address"),contact.getPrmAddress());
		type(By.name("home"),contact.getPrmPhone());
		type(By.name("mobile"),contact.getMobPhone());
		type(By.name("work"),contact.getWrkPhone());
		type(By.name("email"),contact.getPrmEmail());
		type(By.name("email2"),contact.getSecEmail());
		fillBirthDay(contact.getBrthDayCal());
		
		if (formType==CREATION) {
			// selectByText(By.name("new_group"),contact.getGroup());
		} else {
			if (driver.findElements(By.name("new_group")).size() != 0) {
				throw new Error("Group selector exist in contact modification form");
			}
		}
		type(By.name("address2"),contact.getSecAddress());
		type(By.name("phone2"),contact.getSecPhone());
		return this;
	}

	private void fillBirthDay(Calendar brthDayCal) {
		if (brthDayCal!=null){
			select(By.name("bday"),brthDayCal.get(Calendar.DAY_OF_MONTH));
			select(By.name("bmonth"),brthDayCal.get(Calendar.MONTH)+1);
			type(By.name("byear"),String.valueOf(brthDayCal.get(Calendar.YEAR)));
		}
	}

	public ContactData extractContactDataFromEditForm() {
		ContactData contact = new ContactData()
			.withFName(extractTextFromInput(By.name("firstname")))
			.withLName(extractTextFromInput(By.name("lastname")))
			.withPrmAddress(extractTextFromInput(By.name("address")))
			.withPrmPhone(extractTextFromInput(By.name("home")))
			.withMobPhone(extractTextFromInput(By.name("mobile")))
			.withWrkPhone(extractTextFromInput(By.name("work")))
			.withPrmEmail(extractTextFromInput(By.name("email")))
			.withSecEmail(extractTextFromInput(By.name("email2")))
					
	//		TODO: TBD/ implement extracting birthday from contact edit form  
	
			.withSecAddress(extractTextFromInput(By.name("address2")))
			.withSecPhone(extractTextFromInput(By.name("phone2")));
		
		return contact;
	}
}
